package persistencia;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import modelo.Categoria;
import modelo.Idioma;
import modelo.Pagina;

public class BD_operaciones extends Thread{
	private Connection conexion;
	private BD base_datos;
	private Buffer buffer;
	private boolean ha_terminado_crawler;
	
	public BD_operaciones(Buffer buffer)
	{
		base_datos=new BD();
		this.buffer=buffer;
		ha_terminado_crawler=false;
	}
	
	
	public void run()
	{
		Object obj;
		
		while(!ha_terminado_crawler)
		{
			if(buffer.isEmpty())
				try {
					sleep(5*1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}			
			
			obj=buffer.get();
			
			if(obj!=null)
				ejecutar_operacion(obj);
		}
	}
	
	private void ejecutar_operacion (Object obj)
	{
		try
		{
			if(obj instanceof Insertar_Categorias)
			{
				Insertar_Categorias ic =(Insertar_Categorias)obj;
				insertar_categorias(ic.idioma, ic.categorias);			
			}
			else if (obj instanceof Insertar_Hijas)
			{
				Insertar_Hijas ih=(Insertar_Hijas)obj;
				insertar_hijas(ih.idioma, ih.nombre_categoria, ih.categorias_hijas, ih.paginas_hijas);
			}
			else if (obj instanceof Insertar_Paginas)
			{
				Insertar_Paginas ip=(Insertar_Paginas)obj;
				insertar_paginas(ip.idioma, ip.paginas);
			}
			else if (obj instanceof Insertar_Traduccion)
			{
				Insertar_Traduccion it=(Insertar_Traduccion)obj;
				insertar_traduccion(it.idioma_origen, it.pagina_origen, it.pagina_traduccion);
			}
			else
			{
				String nombre_clase=obj.getClass().getName();
				throw new Exception("Objeto no valido en la cola, clase: "+nombre_clase);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	 
	public void insertar_categorias(int idioma, List <String> paginas) throws SQLException, Exception
	{
		String tabla;
		
		if(conexion == null || conexion.isClosed())
			conexion = base_datos.abreConexion();
		
		if(idioma == Idioma.ENGLISH)
			tabla = "categoria_eng";
		else
			tabla = "categoria_esp";			
		
				
		StringBuffer sql_pagina =new StringBuffer();
		sql_pagina.append("INSERT INTO " + tabla +"(TX_URL) VALUES ");
		sql_pagina.append(get_sql_valores(paginas));
		
		System.out.println("\n"+sql_pagina+"\n");
		
		PreparedStatement insertSQL = conexion.prepareStatement(sql_pagina.toString());
		insertSQL.executeUpdate();
	}
	
	
	public void insertar_paginas(int idioma, List <String> paginas) throws SQLException, Exception 
	{
		String tabla;
		
		if(conexion == null || conexion.isClosed())
			conexion = base_datos.abreConexion();
		
		if(idioma == Idioma.ENGLISH)
			tabla = "pagina_eng";
		else
			tabla = "pagina_esp";			
		
				
		StringBuffer sql_pagina =new StringBuffer();
		sql_pagina.append("INSERT INTO " + tabla +"(TX_URL) VALUES ");
		sql_pagina.append(get_sql_valores(paginas));
		
		PreparedStatement insertSQL = conexion.prepareStatement(sql_pagina.toString());
		insertSQL.executeUpdate();
		
		/*insertSQL.setString(1, pag.getUrl());
		insertSQL.setInt(2, 0);
		insertSQL.setInt(3, 0);
		insertSQL.setInt(4, 0);
		insertSQL.setLong(5, 0);
		insertSQL.setInt(6, 0);
		insertSQL.setLong(7, 0);
		insertSQL.setInt(8, 0);
		insertSQL.setInt(9, 0);
		insertSQL.setInt(10, 0);
		insertSQL.setInt(11, 0);
		insertSQL.setInt(12, 0);
		insertSQL.setInt(13, 0);
		*/		
	}
	
	public void insertar_hijas(int idioma, String nombre_categoria, List <String> categorias_hijas, List <String> paginas_hijas)
	{}
	
	public void insertar_traduccion(int idioma_origen, String pagina_origen, String pagina_traduccion)
	{}
	
	public static StringBuffer get_sql_valores (List <String> valores)
	{
		boolean es_primero=true;
		StringBuffer sentencia=new StringBuffer();
		String elemento;
		
		Iterator<String> it=valores.iterator();
		
		while(it.hasNext())
		{
			elemento=it.next();

			if(elemento.endsWith("\\\\"))
				elemento+="\\\\";
			else if(elemento.endsWith("\\"))
				elemento+="\\";
				
			elemento=elemento.replaceAll("'", "\\\\'");
			
			if(es_primero)
			{
				sentencia.append("('"+elemento+"')");	
				es_primero=false;
			}
			else
				sentencia.append(",('"+elemento+"')");
		}		
		
		return sentencia;
	}
	
	
	
	/**
	 * @return the conexion
	 */
	public Connection getConexion() {
		return conexion;
	}

	public void crea_pagina (Pagina pag) throws Exception{
		String tabla;
		
		if(conexion == null || conexion.isClosed())
			conexion = base_datos.abreConexion();
		
		if(pag.getIdioma() == Idioma.ENGLISH)
		{
			tabla = "paginaeng";
			//tabla_relaciones="rel_pageng_cateng";
		}
		else
		{
			tabla = "paginaesp";
			//tabla_relaciones="rel_pagesp_catesp";
		}
				
		String sql_pagina = "INSERT INTO " + tabla 
			+ "(TX_URL, NU_EnlaceInterno, NU_EnlaceExterno, NU_Imagenes, NU_Palabras, NU_Parrafos, NU_PalabrasDistintas, NU_Secciones, NU_Entidades, NU_EntidadesLOC, NU_EntidadesPER, NU_EntidadesORG, NU_EntidadesMISC) " +
					"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
		
		PreparedStatement insertSQL = conexion.prepareStatement(sql_pagina);		
		insertSQL.setString(1, pag.getUrl());
		insertSQL.setInt(2, pag.getNoEnlaceInterno());
		insertSQL.setInt(3, pag.getNoEnlaceExterno());
		insertSQL.setInt(4, pag.getNoImagenes());
		insertSQL.setLong(5, pag.getNoPalabras());
		insertSQL.setInt(6, pag.getNoParrafos());
		insertSQL.setLong(7, pag.getNoPalabrasDistintas());
		insertSQL.setInt(8, pag.getNoSecciones());
		insertSQL.setInt(9, pag.getNoEntidades());
		insertSQL.setInt(10, pag.getNoEntidadesLOC());
		insertSQL.setInt(11, pag.getNoEntidadesPER());
		insertSQL.setInt(12, pag.getNoEntidadesORG());
		insertSQL.setInt(13, pag.getNoEntidadesMISC());
		
		insertSQL.executeUpdate();
		
		/*
		 * if(pag.getCategorias() != null)
			insertSQL.setLong(2, pag.getCategorias().getId());
		else
			insertSQL.setNull(2, Types.BIGINT);
		*/
	}
	
	
	public void crea_categoria(Categoria cat) throws Exception{
		String tabla;
		
		if(conexion == null || conexion.isClosed())
			conexion = base_datos.abreConexion();
		
		if(cat.getIdioma() == Idioma.ENGLISH)
		{
			tabla = "categoriaeng";
		}
		else
		{
			tabla = "categoriaesp";
		}
				
		String sql_pagina = "INSERT INTO " + tabla 
			+ "(TX_URL) VALUES (?)";
		
		PreparedStatement insertSQL = conexion.prepareStatement(sql_pagina);		
		insertSQL.setString(1, cat.getNombre());
		insertSQL.executeUpdate();
	}
	
	
	public void add_categorias_hijas(Categoria cat) throws Exception{
		
		String tabla;
		
		if(conexion == null || conexion.isClosed())
			conexion = base_datos.abreConexion();
		
		if(cat.getIdioma() == Idioma.ENGLISH)
		{
			tabla = "categoriaeng";
		}
		else
		{
			tabla = "categoriaesp";
		}
				
		String categorias_hijas="(";
		Iterator<String> it=cat.getNombres_Categorias_hijas().iterator();
		while(it.hasNext())
			categorias_hijas+=it.next()+",";
		categorias_hijas=categorias_hijas.substring(0, categorias_hijas.length()-1);
		categorias_hijas+=")";
		
		String sql_pagina = "INSERT INTO " + tabla 
			+ "(TX_Nombre) VALUES (?)";
		
		PreparedStatement insertSQL = conexion.prepareStatement(sql_pagina);		
		insertSQL.setString(1, cat.getNombre());
		insertSQL.executeUpdate();
	}
	
	public List<Pagina> consulta(Pagina pag){
		List<Pagina> res = new ArrayList<Pagina>();
		
		return res;
	}
	
	public static boolean borra(Pagina pag){
		boolean res = false;
		
		return res;
	}
	
	
	public class Insertar_Paginas
	{
		public List <String> paginas;
		public int idioma;
	}
	
	public class Insertar_Categorias
	{
		public List <String> categorias;
		public int idioma;
	}
	
	public class Insertar_Traduccion
	{
		public String pagina_origen, pagina_traduccion;
		public int idioma_origen;
	}
	
	public class Insertar_Hijas
	{
		public int idioma;
		public String nombre_categoria;
		public List <String> categorias_hijas; 
		public List <String> paginas_hijas; 
	}
	
	/**
	 * Dada una pagina, a que categorias pertenece
	 * */
	public class Insertar_Categoria_De_Pagina
	{
		public int idioma;
		public String nombre_pagina;
		public List <String> categorias; 
	}
	
	/**
	 * Dada una pagina, las paginas q contiene
	 * */
	public class Insertar_Imagenes_De_Pagina
	{
		public int idioma;
		public String nombre_pagina;
		public List <String> imagenes; 
	}
}
